package com.party.web.biz.crowdfundMultiple;

import com.google.common.base.Function;
import com.google.common.collect.Maps;
import com.party.common.paging.Page;
import com.party.common.utils.BigDecimalUtils;
import com.party.common.utils.DateUtils;
import com.party.common.utils.LangUtils;
import com.party.common.utils.StringUtils;
import com.party.core.model.YesNoStatus;
import com.party.core.model.activity.Activity;
import com.party.core.model.crowdfund.*;
import com.party.core.model.order.OrderStatus;
import com.party.core.service.activity.IActivityService;
import com.party.core.service.cos.CosBizService;
import com.party.core.service.crowdfund.*;
import com.party.core.service.order.IOrderFormService;
import com.party.core.utils.MyBeanUtils;
import com.party.web.biz.crowdfund.ProjectBizService;
import com.party.web.biz.file.FileBizService;
import com.party.web.web.dto.output.crowdfund.ProjectForActivityMultiOutput;
import com.party.web.web.dto.output.crowdfund.ProjectForActivityOutput;
import com.sun.istack.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @ClassName ProjectMultipleBizService
 * @Description TODO
 * @Author yifeng
 * @Date 2019/3/25 10:12
 **/
@Service
public class ProjectMultipleBizService {
    Logger logger = LoggerFactory.getLogger(getClass());
    @Autowired
    private IProjectService projectService;
    @Autowired
    private FileBizService fileBizService;
    @Autowired
    private CosBizService cosBizService;
    @Autowired
    private IEventGradationService eventGradationService;
    @Autowired
    private IProjectGradationService projectGradationService;
    @Autowired
    private IProjectInfoGradationService projectInfoGradationService;
    @Autowired
    private IActivityService activityService;
    @Autowired
    private IOrderFormService orderFormService;
    @Autowired
    private ITargetProjectService targetProjectService;
    @Autowired
    private ProjectBizService projectBizService;

    @Value("#{party['mic.url']}")
    private String micUrl;

    /**
     * @param activityId
     * @param projectWithAuthor
     * @param page
     * @return
     * @Author yifeng
     * @Description 按阶段分众筹人员列表
     * @Date 17:50 2019/3/21
     **/
    public Map<String, Object> listForActivity(String activityId, ProjectWithAuthor projectWithAuthor, Page page) {
        Activity activity = activityService.get(activityId);
        Map<String, Object> listCommon = eventGradations(activity.getEventId(), projectWithAuthor.getCurrentGradation());
        String currentGradation = listCommon.get("currentGradation").toString();
        projectWithAuthor.setCurrentGradation(currentGradation);
        projectWithAuthor.setTargetId(activityId);
        projectWithAuthor.setPayType(0);
        projectWithAuthor.setDistribution(true);
        List<ProjectForActivityOutput> activityOutputs = projectQueryCommon(projectWithAuthor, currentGradation, page);
        listCommon.put("outputList", activityOutputs);
        listCommon.put("activity", activity);
        EventGradation eventGradation = eventGradationService.get(currentGradation);
        if (null == eventGradation || eventGradation.getEndTime().before(new Date())) {
            listCommon.put("showSetCompetitionStatus", true);
        } else {
            listCommon.put("showSetCompetitionStatus", false);
        }
        return listCommon;
    }

    /**
     * @param projectWithAuthor
     * @param page
     * @param currentGradation
     * @return
     * @Author yifeng
     * @Description 主题的众筹列表
     * @Date 16:44 2019/3/25
     **/
    public Map<String, Object> listForEvent(ProjectWithAuthor projectWithAuthor, Page page, String currentGradation) {
        Map<String, Object> listCommon = eventGradations(projectWithAuthor.getEventId(), currentGradation);

        // 支付总额
        Double payMoney = orderFormService.getOrderData(projectWithAuthor.getEventId(),
                OrderStatus.ORDER_STATUS_HAVE_PAID.getCode(), 0);
        // 退款总额
        Double refundMoney = orderFormService.getOrderData(projectWithAuthor.getEventId(),
                OrderStatus.ORDER_STATUS_REFUND.getCode(), 0);
        // 已消费的总额
        Double consumedAmount = projectGradationService.getConsumedAmount(projectWithAuthor.getEventId());
        // 剩余金额
        Double remindAmount = BigDecimalUtils.sub(payMoney, consumedAmount);
        // 总金额
        Double totalMoney = BigDecimalUtils.add(payMoney, refundMoney);
        listCommon.put("refundMoney", BigDecimalUtils.round(refundMoney, 2));
        listCommon.put("consumedAmount", BigDecimalUtils.round(consumedAmount, 2));
        listCommon.put("remainMoney", BigDecimalUtils.round(remindAmount, 2));
        listCommon.put("totalMoney", BigDecimalUtils.round(totalMoney, 2));
        currentGradation = listCommon.get("currentGradation").toString();
        projectWithAuthor.setPayType(0);
        List<ProjectForActivityOutput> activityOutputs = projectQueryCommon(projectWithAuthor, currentGradation, page);
        listCommon.put("outputList", activityOutputs);
        return listCommon;
    }

    /**
     * @param eventId          主题id
     * @param currentGradation 当前阶段id
     * @return
     * @Author yifeng
     * @Description 获取主题的活动阶段数据
     * @Date 15:52 2019/3/25
     **/
    public Map<String, Object> eventGradations(String eventId, String currentGradation) {
        List<EventGradation> eventGradations = eventGradationService.findByEventId(eventId);
        // 当前时间处在的阶段
        EventGradation ongoingGradation = eventGradationService.findOngoingGradation(eventId);
        if (StringUtils.isEmpty(currentGradation)) {
            if (null != ongoingGradation) {
                currentGradation = ongoingGradation.getId();
            } else {
                currentGradation = eventGradations.get(0).getId();
            }
        }

        Map<String, Object> map = Maps.newHashMap();
        map.put("eventGradations", eventGradations);
        map.put("currentGradation", currentGradation);
        map.put("ongoingGradation", ongoingGradation);
        return map;
    }

    /**
     * @param projectWithAuthor
     * @param currentGradation
     * @param page
     * @return
     * @Author yifeng
     * @Description 众筹列表
     * @Date 15:53 2019/3/25
     **/
    public List<ProjectForActivityOutput> projectQueryCommon(ProjectWithAuthor projectWithAuthor, String currentGradation, Page page) {
        Map<String, Object> queryParams = Maps.newHashMap();
        queryParams.put("currentGradationId", currentGradation);
        List<ProjectWithAuthorOutput> projectWithAuthors = projectService.listForActGradation(projectWithAuthor, queryParams, page);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        List<ProjectForActivityOutput> projectForActivityOutputList = LangUtils.transform(projectWithAuthors, projectWithAuthor1 -> {
            if (ProjectGradation.DEFAULT_SUCCESS_TIME.equals(sdf.format(projectWithAuthor1.getSuccessTime()))) {
                projectWithAuthor1.setIsSuccess(0);
            } else {
                projectWithAuthor1.setIsSuccess(1);
            }
            String filePath = fileBizService.getUploadCIPath("crowdfund", projectWithAuthor1.getAuthorId());
            ProjectForActivityOutput output = ProjectForActivityOutput.transform(projectWithAuthor1);
            String codeUrl = cosBizService.getPreviewPictureUrl(filePath + projectWithAuthor1.getId());
            String url = micUrl + "project/project_multi_detail.html?id=" + projectWithAuthor1.getId();
            output.setQrCodeUrl(codeUrl);
            output.setUrl(url);
            Double remindAmount = BigDecimalUtils.sub(projectWithAuthor1.getActualAmount(), projectWithAuthor1.getAllConsumedAmount());
            output.setRemindAmount(BigDecimalUtils.round(remindAmount, 2));
            return output;
        });
        return projectForActivityOutputList;
    }

    /**
     * @param projectGradation 设为不参赛的众筹阶段
     * @return void
     * @Author yifeng
     * @Description 转移
     * @Date 9:57 2019/3/25
     **/
    public boolean transfer(ProjectGradation projectGradation) {
        try {
            Project project = projectService.get(projectGradation.getProjectId());
            if (null == project) {
                throw new Exception("project不能为空");
            }
            EventGradation eventGradation = eventGradationService.get(projectGradation.getEventGradationId());
            if (null != eventGradation) {
                List<EventGradation> nextGradations = eventGradationService.getNextGradations(eventGradation);

                EventGradation endGradation = eventGradationService.getTheLastGradation(eventGradation.getEventId());
                if (null != endGradation && endGradation.getId().equals(projectGradation.getEventGradationId())) {
                    projectGradation.setCompetitionStatus(YesNoStatus.NO.getCode());
                    projectGradationService.update(projectGradation);
                } else {
                    /**
                     * 1.当前阶段的筹满时间设为默认值
                     * 2.useTime设为0
                     **/
                    projectGradation.setCompetitionStatus(YesNoStatus.NO.getCode());
                    projectGradation.setUseTime(0L);
                    projectGradation.setSuccessTime(DateUtils.parse(ProjectGradation.DEFAULT_SUCCESS_TIME, DateUtils.DATE_PATTERN));
                    projectGradationService.update(projectGradation);
                }

                // 如果为空，说明可能是最后一个阶段
                if (null != nextGradations && nextGradations.size() > 0) {
                    // 上个阶段的截止时间
                    Date lastEndTime;
                    for (int i = 0; i < nextGradations.size(); i++) {
                        project = projectService.get(projectGradation.getProjectId());
                        // 累计已筹的真实金额
                        Float realTimeAmount = project.getRealTimeAmount();
                        EventGradation nextGradation = nextGradations.get(i);
                        lastEndTime = nextGradation.getEndTime();
                        if (nextGradation.getEndTime().before(new Date())) {
                            continue;
                        }
                        ProjectGradation nextProjectGradation = projectGradationService.
                                getUnique(new ProjectGradation(projectGradation.getProjectId(), nextGradation.getId()));
                        if (null == nextProjectGradation) {
                            throw new Exception("主题阶段对应的众筹阶段为空：projectId:"
                                    + projectGradation.getProjectId() + ", eventGradationId：" + nextGradation.getId());
                        }
                        Double effectiveAmount = projectGradationService.getEffectiveAmount(lastEndTime, projectGradation.getProjectId());
                        Double subAmount = BigDecimalUtils.sub(realTimeAmount, effectiveAmount);
                        subAmount = BigDecimalUtils.round(subAmount, 2);
                        Long useTime = System.currentTimeMillis() - lastEndTime.getTime();
                        if (subAmount >= nextGradation.getPrice()) {
                            // 如果剩余金额大于目标金额，设为已筹满
                            nextProjectGradation.setSuccessTime(new Date());
                            nextProjectGradation.setCompetitionStatus(3); // 设为空
                            nextProjectGradation.setUseTime(useTime);
                            projectGradationService.update(nextProjectGradation);

                            if (i == nextGradations.size() - 1) {
                                projectService.updateIsSuccess(YesNoStatus.YES.getCode(), project.getId());
                            }
                        } else {
                            nextProjectGradation.setCompetitionStatus(3); // 设为空
                            nextProjectGradation.setUseTime(0L);
                            nextProjectGradation.setSuccessTime(DateUtils.parse(ProjectGradation.DEFAULT_SUCCESS_TIME, DateUtils.DATE_PATTERN));
                            projectGradationService.update(nextProjectGradation);

                            ProjectInfoGradation infoGradation = projectInfoGradationService.findByProjectId(projectGradation.getProjectId());
                            infoGradation.setProjectGradationId(nextProjectGradation.getId());
                            projectInfoGradationService.update(infoGradation);
                            break;
                        }
                    }
                }

                Integer successCount = projectGradationService.getEffectiveCount(projectGradation.getProjectId());
                try {
                    if (successCount == 0) {
                        TargetProject targetProject = targetProjectService.findByProjectId(projectGradation.getProjectId());
                        if (null != targetProject) {
                            Activity activity = activityService.get(targetProject.getTargetId());
                            if (null != activity) {
                                activity.setCrowdfundedNum(activity.getCrowdfundedNum() - 1);
                                activity.setBeCrowdfundNum(activity.getBeCrowdfundNum() + 1);
                                activityService.update(activity);
                            }
                        }
                    }
                } catch (Exception e) {
                    logger.error("处理转移的活动冗余数异常", e);
                }

                try {
                    if (successCount > 0) {
                        new Thread(() -> {
                            projectBizService.getProjectPoster(projectGradation.getProjectId());
                        }).start();
                    }
                } catch (Exception e) {
                    logger.error("绘制众筹成功海报异常", e);
                }
            }
            return true;
        } catch (Exception e) {
            logger.error("转移异常", e);
            return false;
        }
    }

    public List<ProjectForActivityMultiOutput> listForEventExport(ProjectWithAuthor project) {
        project.setPayType(0);
        List<ProjectForActivityOutput> projectForActivityOutputList = projectQueryCommon(project, project.getCurrentGradation(), null);
        List<ProjectForActivityMultiOutput> multiOutputs = LangUtils.transform(projectForActivityOutputList, new Function<ProjectForActivityOutput, ProjectForActivityMultiOutput>() {
            @Nullable
            @Override
            public ProjectForActivityMultiOutput apply(@Nullable ProjectForActivityOutput input) {
                ProjectForActivityMultiOutput output = new ProjectForActivityMultiOutput();
                try {
                    MyBeanUtils.copyBeanNotNull2Bean(input, output);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                if (null != input.getCompetitionStatus()) {
                    output.setCompStatus(YesNoStatus.getValue(input.getCompetitionStatus()));
                }
                return output;
            }
        });
        return multiOutputs;
    }
}